package com.framework.dbs.vo;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.framework.bas.bs.IPlmBasBS;
import com.framework.bas.exception.BasException;
import com.framework.bas.util.SpringUtil;
import com.framework.bas.util.UtilReflect;

public abstract class BaseObject implements Serializable{
    private static final long serialVersionUID = 1L;
    protected IPlmBasBS getBasBS(){
    	return SpringUtil.getBean(IPlmBasBS.BEAN_ID, IPlmBasBS.class);
    }
    
    /**
     * 通过序列生成ID
     * @return
     */
    public String generateId(){
    	String seqName = getSequenceName();
    	if(seqName != null){
    		return getBasBS().txNewStringKey(seqName, true);
    	}else{ 
    		return null;
    	}
    }
    
    /**
     * 获取序列名称，如果没有返回null
     * @return
     */
    public abstract String getSequenceName();
    
    /**
     * 获取id，如果是int类型可以空实现
     * @return
     */
    public abstract Serializable getId();
    public abstract void setId(String id);
//    public abstract Class<BaseObject> getClass();
    
    public void save(){
    	if(getId() == null){
    		this.setId(this.generateId());
    	}
    	getBasBS().save(this);
    }
    
    /**
     * 更新数据，可以是游离态
     * @param isFree 是否游离状态
     */
    public void update(boolean isFree){
    	if(isFree){
    		BaseObject obj = getBasBS().queryById(getClass(), getId());
    		//反射合并数据
    		Map<String,Object> properties = new HashMap<String, Object>();
    		Map<String,Object> fav = UtilReflect.getFieldAndValue(this);
    		for(String name : fav.keySet()){
    			Object val = fav.get(name);
    			if(val != null){
    				properties.put(name,val);
    			}
    		}
    		try {
				BeanUtils.populate(obj, properties);
			} catch (Exception e) {
				throw new BasException("反射调用，更新数据出错");
			}
    		getBasBS().update(obj);
    	}else{
    		getBasBS().update(this);
    	}
    }
    
    public void delete(){
    	getBasBS().delete(this);
    }
}
